﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using ConvertLib;

namespace Lab2.IVAN.NumberToWords
{
    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine
(@"Правила работы с программой:
  1)Вводимое число в диапазоне от  0 до 10^15
  2) Разделителем между целой и дробной частью должна быть запятая
Введите число:");
        
            string str = Console.ReadLine();
            try {

                double number = Convert.ToDouble(str);
                string s = Convertor.MoneyConvert(number);
                Console.WriteLine(s);
                Console.ReadKey();
            }
           catch  
            {
                Console.WriteLine("Вы ввели некорретные данные.Программа будет закрыта атоматически по нажатию любой клавиши");
                Console.ReadKey();
            }
        }
    }
    public static class Convertor
    {
        static string zero = "ноль";
        static string firstM = "один";
        static string firstF = "одна";
        static string secondM = "два";
        static string secondF = "две";

        static string[] from3till19 = 
        {
            "", "три", "четыре", "пять", "шесть",
            "семь", "восемь", "девять", "десять", "одиннадцать",
            "двенадцать", "тринадцать", "четырнадцать", "пятнадцать",
            "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"
        };

        static string[] tens =
        {
            "", "двадцать", "тридцать", "сорок", "пятьдесят",
            "шестьдесят", "семьдесят", "восемьдесят", "девяносто"
        };

        static string[] hundreds =
        {
            "", "сто", "двести", "триста", "четыреста",
            "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"
        };

        static string[] thousands =
        {
            "", "тысяча", "тысячи", "тысяч"
        };

        static string[] millions =
        {
            "", "миллион", "миллиона", "миллионов"
        };

        static string[] billions =
        {
            "", "миллиард", "миллиарда", "миллиардов"
        };

        static string[] trillions =
        {
            "", "трилион", "трилиона", "триллионов"
        };

        static string[] rubles =
        {
            "", "рубль", "рубля", "рублей"
        };

        static string[] grivnas =
        {
            "", "гривна", "гривны", "гривен"
        };

        static string[] copecks =
        {
            "", "копейка", "копейки", "копеек"
        };

        //проверка на множественность 0 или >=5 для выделения окончания
        static bool IsPlural(int digits)
        {
            if (digits >= 5 || digits == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        // проверка на не множествоенность от 2 до 4 включительно для выделения окончания
        static bool IsSingular(int digits)
        {
            if (digits >= 2 && digits <= 4)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        // метод выделения последней цифры в числе
        static int lastDigit(long EnterNumber)
        {
            long amount = EnterNumber;

            if (amount >= 100)
            {
                amount = amount % 100;
            }

            if (amount >= 20)
            {
                amount = amount % 10;
            }

            return (int)amount;
        }

        //главный метод конвертации
        public static string MoneyConvert(double EnterNumber)
        {
            if ((EnterNumber >= (long)Math.Pow(10, 15)) || EnterNumber < 0)
            {
                return "Введите число большее 0  и меньше чем 10 ^ 15";
            }

            long rublesAmount = (long)Math.Floor(EnterNumber);                  //определение целого числа рублей
            long copecksAmount = ((long)Math.Round(EnterNumber * 100)) % 100;   //определение целого числа копеек
            int lastRublesDigit = lastDigit(rublesAmount);                 // оределение последней цифры в колличесве рублей
            int lastCopecksDigit = lastDigit(copecksAmount);               //оределение последней цифры в колличесве копеек

            string s = NumeralsToTxt(rublesAmount) + " ";
            // добавление валюты
            if (IsPlural(lastRublesDigit))
            {
                s = s + grivnas[3] + " "; // гривен
            }
            else if (IsSingular(lastRublesDigit))
            {
                s = s + grivnas[2] + " "; // гривны
            }
            else
            {
                s = s + grivnas[1] + " ";// гривна
            }
            // добавление кол-ва копеек
            s = s + String.Format("{0:00} ", copecksAmount);
            // добавление слова копеек
            if (IsPlural(lastCopecksDigit))
            {
                s = s + copecks[3] + " "; // копееек
            }
            else if (IsSingular(lastCopecksDigit))
            {
                s = s + copecks[2] + " "; // копейки
            }
            else
            {
                s = s + copecks[1] + " "; // копейка
            }
            return s.Trim();
        }
        //разложение входного числа на тройки чисел  для обработки
        public static string NumeralsToTxt(long _sourceNumber)
        {
            string s = "";
            long number = _sourceNumber;// переменная для хранения рабочей версии числа
            int remainder;// последние 3 числа с котрыми работаем
            int power = 0;//счетчик разрядов( колличества троек)

            while (number > 0)
            {
                remainder = (int)(number % 1000);// выделяем текущую тройку(или двойку или единицу)
                number = number / 1000; // убираем трекущую тройку из числа

                switch (power)
                {
                    case 12:
                        s = MakeText(remainder, hundreds, tens, from3till19, secondM, firstM, trillions) + s;// для триллионов
                        break;
                    case 9:
                        s = MakeText(remainder, hundreds, tens, from3till19, secondM, firstM, billions) + s;//для миллиардов
                        break;
                    case 6:
                        s = MakeText(remainder, hundreds, tens, from3till19, secondM, firstM, millions) + s;// для милионов
                        break;
                    case 3:
                        s = MakeText(remainder, hundreds, tens, from3till19, secondF, firstF, thousands) + s;// для тысяч
                        break;
                    default:
                        string[] powerArray = { };
                        s = MakeText(remainder, hundreds, tens, from3till19, secondM, firstM, powerArray) + s; //для чисел меьше 1000
                        break;
                }

                power += 3;
            }
            //отсутствующий разряд заменятся пробелом
            if (_sourceNumber == 0)
            {
                s = zero + " ";
            }

            return s;
        }
        //метод который переводит непосредственно выбранные 3 цифры в слова
        static string MakeText(int _digits, string[] _hundreds, string[] _tens, string[] _from3till19, string _second, string _first, string[] _power)
        {
            string s = "";
            int digits = _digits; // сохранияем исходное значение

            if (digits >= 100)
            {
                s = s + _hundreds[digits / 100] + " ";//добавление сотен
                digits = digits % 100;
            }
            if (digits >= 20)
            {
                s = s + _tens[digits / 10 - 1] + " ";// добавление десятков от 99 до 20
                digits = digits % 10;
            }
            if (digits >= 3)
            {
                s = s + _from3till19[digits - 2] + " ";// добавление единиц от 3 до 19
            }
            else if (digits == 2)
            {
                s = s + _second + " "; //добавление двойки 
            }
            else if (digits == 1)
            {
                s = s + _first + " "; // добавление единицы
            }
            // есди работа идет с первой тройкой то ничего е добавляется а если с последующими до добавляется название разрядов
            if (_digits != 0 && _power.Length > 0)
            {
                digits = lastDigit(_digits);

                if (IsPlural(digits))
                {
                    s = s + _power[3] + " ";// тысяч или миллионов и т.д.
                }
                else if (IsSingular(digits))
                {
                    s = s + _power[2] + " "; //тысячи или миллиона и т.д
                }
                else
                {
                    s = s + _power[1] + " "; //тысячя или милион и т.д
                }
            }
            return s;
        }
    }

   
}
